Python'ning http.server (ilgari BaseHTTPServer) modulini moslashtirish bo'yicha to'liq qo'llanma. Sodda API'lar, dinamik veb-serverlar va ichki vositalarni yarating.
Python'ning O'rnatilgan HTTP Serverini O'zlashtirish: Moslashtirishga Chuqur Yondashuv
Python "barchasi o'rnatilgan" falsafasi bilan mashhur bo'lib, dasturchilarga minimal tashqi bog'liqliklar bilan funktsional ilovalar yaratish imkonini beruvchi boy standart kutubxonani taqdim etadi. Ushbu "batareyalar" ning eng foydali, ammo ko'pincha e'tibordan chetda qoladiganlaridan biri bu o'rnatilgan HTTP serveridir. Uni zamonaviy Python 3 nomi, http.server
, yoki eski Python 2 nomi, BaseHTTPServer
bilan bilsangiz ham, bu modul veb protokollarini tushunish va engil veb-xizmatlarni yaratish uchun eshikdir.
Ko'plab dasturchilar uni katalogdagi fayllarni xizmat ko'rsatish uchun bir qatorli buyruq sifatida uchratishsa-da, uning haqiqiy kuchi kengayish imkoniyatlarida yotadi. Uning asosiy komponentlaridan kichik sinf yaratish orqali siz ushbu oddiy fayl serverini maxsus moslashtirilgan veb-ilovaga, frontend dasturlash uchun soxta API'ga, IoT qurilmalari uchun ma'lumot qabul qiluvchiga yoki kuchli ichki vositaga aylantirishingiz mumkin. Ushbu qo'llanma sizni asosiy bilimlardan tortib to ilg'or moslashtirishgacha olib boradi va ushbu ajoyib moduldan o'z loyihalaringiz uchun foydalanishga tayyorlaydi.
Asoslar: Buyruq Qatoridan Oddiy Server
Kodga kirishdan oldin, eng keng tarqalgan foydalanish holatini ko'rib chiqaylik. Agar sizda Python o'rnatilgan bo'lsa, sizda allaqachon veb-server mavjud. Terminal yoki buyruq satri yordamida kompyuteringizdagi istalgan katalogga o'ting va quyidagi buyruqni ishga tushiring (Python 3 uchun):
python -m http.server 8000
Bir zumda, sizning joriy joylashuvingizdagi fayllar va kichik kataloglarga xizmat ko'rsatadigan 8000 portida ishlaydigan veb-serverga ega bo'lasiz. Unga brauzeringizdan http://localhost:8000
orqali kirishingiz mumkin. Bu quyidagilar uchun nihoyatda foydalidir:
- Fayllarni mahalliy tarmoq orqali tezda ulashish.
- Murakkab sozlamalarsiz oddiy HTML, CSS va JavaScript loyihalarini sinovdan o'tkazish.
- Veb-server turli so'rovlarni qanday boshqarishini tekshirish.
Biroq, bu bir qatorli buyruq shunchaki muz tog'ining uchi. U oldindan tayyorlangan, umumiy serverni ishga tushiradi. Maxsus mantiqni qo'shish, turli so'rov turlarini boshqarish yoki dinamik kontent yaratish uchun biz o'zimizning Python skriptimizni yozishimiz kerak.
Asosiy Komponentlarni Tushunish
Ushbu modul yordamida yaratilgan veb-server ikki asosiy qismdan iborat: server va ishlovchi (handler). Ularning alohida rollarini tushunish samarali moslashtirish uchun kalit hisoblanadi.
1. Server: HTTPServer
Serverning vazifasi ma'lum bir manzil va portda kiruvchi tarmoq ulanishlarini tinglashdir. Bu TCP ulanishlarini qabul qiladigan va ularni qayta ishlash uchun ishlovchiga (handler) uzatadigan dvigatirdir. http.server
modulida bu odatda HTTPServer
sinfi tomonidan boshqariladi. Unga server manzilini (('localhost', 8000)
kabi tuple) va ishlovchi sinfini taqdim etish orqali uning namunasini yaratasiz.
Uning asosiy mas'uliyati tarmoq soketini boshqarish va so'rov-javob siklini tashkillashtirishdir. Ko'pgina moslashtirishlar uchun siz HTTPServer
sinfining o'zini o'zgartirishingiz shart emas, lekin u mavjudligini va jarayonni boshqarayotganini bilish muhimdir.
2. Ishlovchi (Handler): BaseHTTPRequestHandler
Sehr bu yerda sodir bo'ladi. Ishlovchi (handler) kiruvchi HTTP so'rovini tahlil qilish, mijoz nimani so'rayotganini tushunish va tegishli HTTP javobini yaratish uchun javobgardir. Har safar server yangi so'rov qabul qilganda, u uni qayta ishlash uchun sizning ishlovchi sinfingizning namunasini yaratadi.
http.server
moduli bir nechta tayyor ishlovchilarni taqdim etadi:
BaseHTTPRequestHandler
: Bu eng asosiy ishlovchi. U so'rovni va sarlavhalarni tahlil qiladi, lekin GET yoki POST kabi aniq so'rov usullariga qanday javob berishni bilmaydi. Hammasini noldan qurmoqchi bo'lganingizda meros qilib olish uchun mukammal asosiy sinf.SimpleHTTPRequestHandler
: BuBaseHTTPRequestHandler
'dan meros oladi va joriy katalogdan fayllarni xizmat ko'rsatish mantig'ini qo'shadi.python -m http.server
buyrug'ini ishga tushirganingizda, siz ushbu ishlovchidan foydalanayotgan bo'lasiz. Agar siz sukut bo'yicha fayl xizmat ko'rsatish xatti-harakatlari ustiga maxsus mantiq qo'shmoqchi bo'lsangiz, bu ajoyib boshlang'ich nuqtadir.CGIHTTPRequestHandler
: BuSimpleHTTPRequestHandler
'ni CGI skriptlarini ham boshqarish uchun kengaytiradi. Bu zamonaviy veb-dasturlashda kamroq uchraydi, ammo kutubxona tarixining bir qismidir.
Deyarli barcha maxsus server vazifalari uchun sizning ishingiz BaseHTTPRequestHandler
yoki SimpleHTTPRequestHandler
dan meros oladigan yangi sinf yaratishni va uning usullarini bekor qilishni o'z ichiga oladi.
Sizning Birinchi Maxsus Serveringiz: "Salom, Dunyo!" Misoli
Keling, buyruq qatoridan chetga chiqib, maxsus xabar bilan javob beradigan server uchun oddiy Python skriptini yozaylik. Biz BaseHTTPRequestHandler
dan meros olamiz va har qanday HTTP GET so'rovlarini boshqarish uchun avtomatik ravishda chaqiriladigan do_GET
usulini amalga oshiramiz.
custom_server.py
nomli fayl yarating:
# Use http.server for Python 3
from http.server import BaseHTTPRequestHandler, HTTPServer
import time
hostName = "localhost"
serverPort = 8080
class MyServer(BaseHTTPRequestHandler):
def do_GET(self):
# 1. Send the response status code
self.send_response(200)
# 2. Send headers
self.send_header("Content-type", "text/html")
self.end_headers()
# 3. Write the response body
self.wfile.write(bytes("<html><head><title>My Custom Server</title></head>", "utf-8"))
self.wfile.write(bytes("<p>Request: %s</p>" % self.path, "utf-8"))
self.wfile.write(bytes("<body>", "utf-8"))
self.wfile.write(bytes("<p>This is a custom server, created with Python's http.server.</p>", "utf-8"))
self.wfile.write(bytes("</body></html>", "utf-8"))
if __name__ == "__main__":
webServer = HTTPServer((hostName, serverPort), MyServer)
print(f"Server started http://{hostName}:{serverPort}")
try:
webServer.serve_forever()
except KeyboardInterrupt:
pass
webServer.server_close()
print("Server stopped.")
Buni ishga tushirish uchun terminalingizda python custom_server.py
buyrug'ini bajaring. Brauzeringizda http://localhost:8080
manziliga kirganingizda, o'zingizning maxsus HTML xabaringizni ko'rasiz. Agar siz boshqa yo'lga, masalan, http://localhost:8080/some/path
manziliga kirsangiz, xabar shu yo'lni aks ettiradi.
Keling, do_GET
usulini ko'rib chiqaylik:
self.send_response(200)
: Bu HTTP holat qatorini yuboradi.200 OK
muvaffaqiyatli so'rov uchun standart javobdir.self.send_header("Content-type", "text/html")
: Bu HTTP sarlavhasini yuboradi. Bu yerda biz brauzerga yuborayotgan kontentimiz HTML ekanligini aytamiz. Bu sahifani to'g'ri ko'rsatish uchun juda muhimdir.self.end_headers()
: Bu HTTP sarlavhalarining tugashini va javob tanasining boshlanishini bildiruvchi bo'sh qatorni yuboradi.self.wfile.write(...)
:self.wfile
- bu javob tanangizni yozishingiz mumkin bo'lgan faylga o'xshash ob'ekt. U baytlarni, satrlarni emas, kutadi, shuning uchun biz HTML satrimiznibytes("...", "utf-8")
yordamida baytlarga kodlashimiz kerak.
Ilg'or Moslashtirish: Amaliy Retseptlar
POST So'rovlarini Boshqarish (do_POST
)
Veb-ilovalar ko'pincha ma'lumotlarni qabul qilishlari kerak bo'ladi, masalan, HTML shaklidan yoki API chaqiruvidan. Bu odatda POST so'rovi bilan amalga oshiriladi. Buni boshqarish uchun siz do_POST
usulini bekor qilasiz.
do_POST
ichida siz so'rov tanasini o'qishingiz kerak. Ushbu tananing uzunligi Content-Length
sarlavhasida ko'rsatilgan.
Bu yerda POST so'rovidan JSON ma'lumotlarini o'qiydigan va uni qayta aks ettiruvchi ishlovchi (handler) misoli keltirilgan:
import json
from http.server import BaseHTTPRequestHandler, HTTPServer
class APIServer(BaseHTTPRequestHandler):
def _send_cors_headers(self):
"""Sends headers to allow cross-origin requests"""
self.send_header("Access-Control-Allow-Origin", "*")
self.send_header("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
self.send_header("Access-Control-Allow-Headers", "X-Requested-With, Content-Type")
def do_OPTIONS(self):
"""Handles pre-flight CORS requests"""
self.send_response(200)
self._send_cors_headers()
self.end_headers()
def do_POST(self):
# 1. Read the content-length header
content_length = int(self.headers['Content-Length'])
# 2. Read the request body
post_data = self.rfile.read(content_length)
# For demonstration, let's log the received data
print(f"Received POST data: {post_data.decode('utf-8')}")
# 3. Process the data (here, we just echo it back as JSON)
try:
received_json = json.loads(post_data)
response_data = {"status": "success", "received_data": received_json}
except json.JSONDecodeError:
self.send_response(400) # Bad Request
self.end_headers()
self.wfile.write(bytes('{\"error\": \"Invalid JSON\"}', "utf-8"))
return
# 4. Send a response
self.send_response(200)
self._send_cors_headers()
self.send_header("Content-type", "application/json")
self.end_headers()
self.wfile.write(json.dumps(response_data).encode("utf-8"))
# Main execution block remains the same...
if __name__ == "__main__":
# ... (use the same HTTPServer setup as before, but with APIServer as the handler)
server_address = ('localhost', 8080)
httpd = HTTPServer(server_address, APIServer)
print('Starting server on port 8080...')
httpd.serve_forever()
CORS bo'yicha izoh: do_OPTIONS
usuli va _send_cors_headers
funksiyasi Cross-Origin Resource Sharing (CORS) ni boshqarish uchun kiritilgan. Agar siz API'ni boshqa manba (domen/port) dan taqdim etiladigan veb-sahifadan chaqirayotgan bo'lsangiz, bu ko'pincha zarurdir.
JSON Javoblari bilan Oddiy API Yaratish
Keling, asosiy marshrutlashga ega server yaratish uchun avvalgi misolni kengaytiramiz. Biz self.path
atributini tekshirib, mijoz qaysi resursni so'rayotganini aniqlashimiz va shunga mos ravishda javob berishimiz mumkin. Bu bizga bitta server ichida bir nechta API endpointlarini yaratish imkonini beradi.
import json
from http.server import BaseHTTPRequestHandler, HTTPServer
from urllib.parse import urlparse, parse_qs
# Mock data
users = {
1: {"name": "Alice", "country": "Canada"},
2: {"name": "Bob", "country": "Australia"}
}
class APIHandler(BaseHTTPRequestHandler):
def _set_headers(self, status_code=200):
self.send_response(status_code)
self.send_header("Content-type", "application/json")
self.send_header("Access-Control-Allow-Origin", "*")
self.end_headers()
def do_GET(self):
parsed_path = urlparse(self.path)
path = parsed_path.path
if path == "/api/users":
self._set_headers()
self.wfile.write(json.dumps(list(users.values())).encode("utf-8"))
elif path.startswith("/api/users/"):
try:
user_id = int(path.split('/')[-1])
user = users.get(user_id)
if user:
self._set_headers()
self.wfile.write(json.dumps(user).encode("utf-8"))
else:
self._set_headers(404)
self.wfile.write(json.dumps({"error": "User not found"}).encode("utf-8"))
except ValueError:
self._set_headers(400)
self.wfile.write(json.dumps({"error": "Invalid user ID"}).encode("utf-8"))
else:
self._set_headers(404)
self.wfile.write(json.dumps({"error": "Not Found"}).encode("utf-8"))
# Main execution block as before, using APIHandler
# ...
Ushbu ishlovchi (handler) bilan serveringiz endi ibtidoiy marshrutlash tizimiga ega bo'ldi:
/api/users
manziliga GET so'rovi barcha foydalanuvchilar ro'yxatini qaytaradi./api/users/1
manziliga GET so'rovi Alice haqidagi ma'lumotlarni qaytaradi.- Boshqa har qanday yo'l 404 Not Found xatosiga olib keladi.
Fayllarni va Dinamik Kontentni Birga Xizmat Ko'rsatish
Agar siz dinamik APIga ega bo'lishni, ammo shu serverdan statik fayllarni (masalan, index.html
) ham taqdim etishni istasangiz-chi? Eng oson yo'li SimpleHTTPRequestHandler
dan meros olish va so'rov sizning maxsus yo'llaringizga mos kelmaganda uning sukutdagi xatti-harakatiga o'tkazishdir.
Bu yerda super()
funksiyasi sizning eng yaxshi do'stingizdir. U sizga ota sinf usulini chaqirish imkonini beradi.
import json
from http.server import SimpleHTTPRequestHandler, HTTPServer
class HybridHandler(SimpleHTTPRequestHandler):
def do_GET(self):
if self.path == '/api/status':
self.send_response(200)
self.send_header('Content-type', 'application/json')
self.end_headers()
response = {'status': 'ok', 'message': 'Server is running'}
self.wfile.write(json.dumps(response).encode('utf-8'))
else:
# For any other path, fall back to the default file-serving behavior
super().do_GET()
# Main execution block as before, using HybridHandler
# ...
Endi, agar siz xuddi shu katalogda index.html
faylini yaratib, ushbu skriptni ishga tushirsangiz, http://localhost:8080/
manziliga tashrif buyurganingizda sizning HTML faylingiz taqdim etiladi, http://localhost:8080/api/status
manziliga tashrif buyurganingizda esa sizning maxsus JSON javobingiz qaytariladi.
Python 2 (BaseHTTPServer
) Haqida Eslatma
Python 2 endi qo'llab-quvvatlanmasa ham, siz uning HTTP serveri versiyasidan foydalanadigan eski kodlarga duch kelishingiz mumkin. Kontseptsiyalar bir xil, ammo modul nomlari farq qiladi. Quyida tezkor tarjima qo'llanmasi keltirilgan:
- Python 3:
http.server
-> Python 2:BaseHTTPServer
,SimpleHTTPServer
- Python 3:
socketserver
-> Python 2:SocketServer
- Python 3:
from http.server import BaseHTTPRequestHandler
-> Python 2:from BaseHTTPServer import BaseHTTPRequestHandler
Usul nomlari (do_GET
, do_POST
) va asosiy mantiq bir xil bo'lib qoladi, bu esa eski skriptlarni Python 3 ga o'tkazishni nisbatan osonlashtiradi.
Ishlab chiqarishga oid Mulohazalar: Qachon Oldinga Siljish Kerak
Python'ning o'rnatilgan HTTP serveri ajoyib vosita, ammo uning cheklovlari bor. Qachon u to'g'ri tanlov ekanligini va qachon yanada mustahkam yechimga murojaat qilish kerakligini tushunish juda muhimdir.
1. Bir vaqtning o'zida ishlash (Concurrency) va Ishlash Unumdorligi (Performance)
Sukut bo'yicha, HTTPServer
bir oqimli (single-threaded) bo'lib, so'rovlarni ketma-ket qayta ishlaydi. Agar bitta so'rovni qayta ishlash uzoq vaqt talab qilsa, u boshqa barcha kiruvchi so'rovlarni bloklaydi. Bir oz ilg'orroq foydalanish holatlari uchun siz ko'p oqimli (multi-threaded) server yaratish uchun socketserver.ThreadingMixIn
dan foydalanishingiz mumkin:
from socketserver import ThreadingMixIn
from http.server import HTTPServer
class ThreadingHTTPServer(ThreadingMixIn, HTTPServer):
"""Handle requests in a separate thread."""
pass
# In your main block, use this instead of HTTPServer:
# webServer = ThreadingHTTPServer((hostName, serverPort), MyServer)
Bu bir vaqtning o'zida ishlashga yordam bersa-da, yuqori unumdorlikka, yuqori trafikli ishlab chiqarish muhitlariga mo'ljallanmagan. To'liq veb-freymvorklar va dastur serverlari (Gunicorn yoki Uvicorn kabi) unumdorlik, resurslarni boshqarish va masshtablanuvchanlik uchun optimallashtirilgan.
2. Xavfsizlik
http.server
xavfsizlikni asosiy e'tibor sifatida qurilmagan. Unda Cross-Site Scripting (XSS), Cross-Site Request Forgery (CSRF) yoki SQL in'ektsiyasi kabi keng tarqalgan veb zaifliklariga qarshi o'rnatilgan himoya vositalari mavjud emas. Django, Flask va FastAPI kabi ishlab chiqarish darajasidagi freymvorklar bu himoyalarni qutidan tashqarida taqdim etadi.
3. Xususiyatlar va Abstraction
Ilovangiz o'sib borishi bilan siz ma'lumotlar bazasi integratsiyasi (ORMlar), shablon dvigatellari, murakkab marshrutlash, foydalanuvchi autentifikatsiyasi va middleware kabi xususiyatlarni xohlaysiz. Bularning barchasini http.server
ustida o'zingiz qurishingiz mumkin bo'lsa-da, siz asosan veb-freymvorkni qayta ixtiro qilgan bo'lardingiz. Flask, Django va FastAPI kabi freymvorklar bu komponentlarni yaxshi tuzilgan, sinovdan o'tgan va ta'minlanadigan tarzda taqdim etadi.
http.server
dan foydalaning:
- HTTPni o'rganish va tushunish.
- Tez prototiplash va kontseptsiya isbotlari.
- Oddiy, faqat ichki vositalar yoki boshqaruv panellari yaratish.
- Frontend dasturlash uchun soxta API serverlari yaratish.
- IoT yoki skriptlar uchun engil ma'lumot yig'ish endpointlari.
Freymvorkka o'ting:
- Jamoatchilikka ochiq veb-ilovalar.
- Autentifikatsiya va ma'lumotlar bazasi bilan o'zaro aloqali murakkab APIlar.
- Xavfsizlik, unumdorlik va masshtablanuvchanlik muhim bo'lgan ilovalar.
Xulosa: Oddiylik va Nazoratning Kuchi
Python'ning http.server
moduli tilning amaliy dizayniga dalildir. U veb-protokollari bilan ishlashi kerak bo'lgan har bir kishi uchun oddiy, ammo kuchli asosni ta'minlaydi. Uning so'rov ishlovchilarini moslashtirishni o'rganish orqali siz so'rov-javob sikli ustidan nozik nazoratga ega bo'lasiz, bu sizga to'liq veb-freymvorkning ortiqcha yukisiz ko'plab foydali vositalarni yaratish imkonini beradi.
Keyingi safar tezkor veb-xizmat, soxta API kerak bo'lganda yoki shunchaki HTTP bilan tajriba o'tkazmoqchi bo'lganingizda, ushbu ko'p qirrali modulni eslang. U shunchaki fayl serveridan ko'proq narsa; bu Python standart kutubxonasiga kiritilgan, veb-ga asoslangan ijodlaringiz uchun bo'sh kanvasdir.